/*
 * Copyright (C), 2002-2015, 苏宁易购电子商务有限公司
 * FileName: WorkOrderDBOperation.java
 * Author:   admin
 * Date:     2015年12月22日 下午4:57:32
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.app.snpaasadmin.operation;

import com.suning.app.snpaasadmin.dao.CfWorkorderMapper;
import com.suning.app.snpaasadmin.dao.CfWorkorderOperationMapper;
import com.suning.app.snpaasadmin.dao.CfWorkorderReplyMapper;
import com.suning.app.snpaasadmin.domain.WorkOrderBean;
import com.suning.app.snpaasadmin.domain.WorkOrderResult;
import com.suning.app.snpaasadmin.pojo.CfWorkOrderExternal;
import com.suning.app.snpaasadmin.pojo.CfWorkorder;
import com.suning.app.snpaasadmin.pojo.CfWorkorderExample;
import com.suning.app.snpaasadmin.pojo.CfWorkorderOperation;
import com.suning.app.snpaasadmin.pojo.CfWorkorderOperationExample;
import com.suning.app.snpaasadmin.pojo.CfWorkorderReply;
import com.suning.app.snpaasadmin.pojo.CfWorkorderReplyExample;
import com.suning.app.snpaasadmin.util.Constants;
import com.suning.app.snpaasadmin.util.DbContextHolder;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author admin
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class WorkOrderDBOperation {

     @Autowired 
     private CfWorkorderMapper cfWorkOrderMapper;
     
     @Autowired
     private CfWorkorderReplyMapper cfWorkOrderReplyMapper;
     
     @Autowired
     private CfWorkorderOperationMapper operationMapper;
     

    public List<WorkOrderResult> getListUnreadCfWorkorder() throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        List<WorkOrderBean> Unreadworkorders = cfWorkOrderMapper.selectUnreadByUser();
        List<WorkOrderResult> results = new ArrayList<WorkOrderResult>();
        for(WorkOrderBean work : Unreadworkorders) {
            Long createTime = work.getCreateTime().getTime();
            if(work.getUpdateTime() == null ) {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),null,work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            } else {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),work.getUpdateTime().getTime(),work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            }
        }
        return results;
    }

    public List<WorkOrderResult> getListReadCfWorkorder() throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        List<WorkOrderBean> Allworkorders = cfWorkOrderMapper.selectAllWorkorder();
        List<WorkOrderResult> results = new ArrayList<WorkOrderResult>();
        for(WorkOrderBean work : Allworkorders) {
            Long createTime = work.getCreateTime().getTime();
            if(work.getUpdateTime() == null ) {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),null,work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            } else {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),work.getUpdateTime().getTime(),work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            }
        }
        return results;
    }

    public Boolean replyUser(String context, Integer workOrderId, Integer serialNum) throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        CfWorkorderOperation cfWorkorderOp = new CfWorkorderOperation();
        cfWorkorderOp.setContent(context);
        cfWorkorderOp.setCreateTime(new Date());
        cfWorkorderOp.setWorkorderId(workOrderId);
        cfWorkorderOp.setSerialNum(serialNum + 1);
        operationMapper.insertSelective(cfWorkorderOp);
        
        //更新工单的更新时间 根据workorderId查询
        CfWorkorder record = cfWorkOrderMapper.selectByPrimaryKey(workOrderId);
        record.setUpdateTime(new Date());
        cfWorkOrderMapper.updateByPrimaryKeySelective(record);
        return true;
    }
    
    public List<CfWorkOrderExternal> getWorkOrderDetail(Integer workOrderId) throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        List<CfWorkOrderExternal> data = new ArrayList<CfWorkOrderExternal>();
        // 查找该条工单下用户的所有的回复
        CfWorkorderReplyExample cfWorkorderReplyExample = new CfWorkorderReplyExample();
        cfWorkorderReplyExample.createCriteria().andWorkorderIdEqualTo(workOrderId);
        cfWorkorderReplyExample.setOrderByClause(Constants.SQL_ORDERBY);
        List<CfWorkorderReply> replys = cfWorkOrderReplyMapper.selectByExample(cfWorkorderReplyExample);

        // 查找该工单下运维人员的所有回复
        CfWorkorderOperationExample operationExample = new CfWorkorderOperationExample();
        operationExample.createCriteria().andWorkorderIdEqualTo(workOrderId);
        operationExample.setOrderByClause(Constants.SQL_ORDERBY);
        List<CfWorkorderOperation> operations = operationMapper.selectByExample(operationExample);

        Map<String, Integer> map = new HashMap<>();
        map.put("workOrderId", workOrderId);
        List<WorkOrderBean> users= cfWorkOrderMapper.selectUserName(map);
        if(users != null) {
            String userName = users.get(0).getUserName();
            data = mergeWorkOrder(replys, operations, userName);
        }
        CfWorkorderExample cfWOder = new CfWorkorderExample();
        cfWOder.createCriteria().andIdEqualTo(workOrderId);
        List<CfWorkorder> workOrder = cfWorkOrderMapper.selectByExample(cfWOder);
        CfWorkorder cfWorkorder = workOrder.get(0);
        cfWorkorder.setReadState(Constants.WORKORDER_READ);
        cfWorkOrderMapper.updateByPrimaryKeySelective(cfWorkorder);
        return data;
    }

    protected List<CfWorkOrderExternal> mergeWorkOrder(List<CfWorkorderReply> replyList,
            List<CfWorkorderOperation> operationList, String userName) {
        List<CfWorkOrderExternal> workOrderList = new ArrayList<CfWorkOrderExternal>();
        
        int size1 = replyList.size();
        int size2 = operationList.size();
        int i = 0, j = 0, k = 0;
        while (i < size1 && j < size2) {
            if (replyList.get(i).getSerialNum() < operationList.get(j).getSerialNum()) {
                CfWorkorderReply reply = replyList.get(i);
                CfWorkOrderExternal res = new CfWorkOrderExternal();
                res.setWorkOrderId(reply.getWorkorderId());
                res.setContent(reply.getReplyContext());
                res.setCreateTime(reply.getReplyTime().getTime());
                res.setSerialNum(reply.getSerialNum());
                res.setUserType(Constants.WORKORDER_USER);
                res.setUserName(userName);
                workOrderList.add(k++, res);
                i++;
            } else if (replyList.get(i).getSerialNum() == operationList.get(j).getSerialNum()) {
                CfWorkorderReply reply = replyList.get(i);
                CfWorkorderOperation operation = operationList.get(j);
                if (reply.getReplyTime().getTime() > operation.getCreateTime().getTime()) {
                    CfWorkOrderExternal res = new CfWorkOrderExternal();
                    res.setWorkOrderId(operation.getWorkorderId());
                    res.setContent(operation.getContent());
                    res.setCreateTime(operation.getCreateTime().getTime());
                    res.setSerialNum(operation.getSerialNum());
                    res.setUserType(Constants.WORKORDER_CUSTOMER_SERVICE);
                    res.setUserName(userName);
                    workOrderList.add(k++, res);
                    j++;
                } else {
                    CfWorkOrderExternal res = new CfWorkOrderExternal();
                    res.setWorkOrderId(reply.getWorkorderId());
                    res.setContent(reply.getReplyContext());
                    res.setCreateTime(reply.getReplyTime().getTime());
                    res.setSerialNum(reply.getSerialNum());
                    res.setUserType(Constants.WORKORDER_USER);
                    res.setUserName(userName);
                    workOrderList.add(k++, res);
                    i++;
                }
            } else {
                CfWorkorderOperation operation = operationList.get(i);
                CfWorkOrderExternal res = new CfWorkOrderExternal();
                res.setWorkOrderId(operation.getWorkorderId());
                res.setContent(operation.getContent());
                res.setCreateTime(operation.getCreateTime().getTime());
                res.setSerialNum(operation.getSerialNum());
                res.setUserType(Constants.WORKORDER_CUSTOMER_SERVICE);
                res.setUserName(userName);
                workOrderList.add(k++, res);
                j++;
            }
        }
        while (i < size1) {
            CfWorkOrderExternal res = new CfWorkOrderExternal();
            CfWorkorderReply reply = replyList.get(i);
            res.setWorkOrderId(reply.getWorkorderId());
            res.setContent(reply.getReplyContext());
            res.setCreateTime(reply.getReplyTime().getTime());
            res.setSerialNum(reply.getSerialNum());
            res.setUserType(Constants.WORKORDER_USER);
            res.setUserName(userName);
            workOrderList.add(k++, res);
            i++;
        }
        while (j < size2) {
            CfWorkorderOperation operation = operationList.get(j);
            CfWorkOrderExternal res = new CfWorkOrderExternal();
            res.setWorkOrderId(operation.getWorkorderId());
            res.setContent(operation.getContent());
            res.setCreateTime(operation.getCreateTime().getTime());
            res.setSerialNum(operation.getSerialNum());
            res.setUserType(Constants.WORKORDER_CUSTOMER_SERVICE);
            res.setUserName(userName);
            workOrderList.add(k++, res);
            j++;
        }
        return workOrderList;
    }
    
    public List<WorkOrderResult> getListHandlingCfWorkorder() throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        List<WorkOrderBean> Unreadworkorders = cfWorkOrderMapper.selectHandlingOrder();
        List<WorkOrderResult> results = new ArrayList<WorkOrderResult>();
        for(WorkOrderBean work : Unreadworkorders) {
            Long createTime = work.getCreateTime().getTime();
            if(work.getUpdateTime() == null ) {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),null,work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            } else {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),work.getUpdateTime().getTime(),work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            }
        }
        return results;
    }
    
    public List<WorkOrderResult> getListCloseCfWorkorder() throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        List<WorkOrderBean> Unreadworkorders = cfWorkOrderMapper.selectCloseOrder();
        List<WorkOrderResult> results = new ArrayList<WorkOrderResult>();
        for(WorkOrderBean work : Unreadworkorders) {
            Long createTime = work.getCreateTime().getTime();
            if(work.getUpdateTime() == null ) {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),null,work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            } else {
                WorkOrderResult workOrderResult = new WorkOrderResult(work.getId(),work.getOrderName(),createTime,
                        work.getOrderContext(),work.getUserId(),work.getReadState(),work.getOrderState(),work.getUpdateTime().getTime(),work.getSerialNum(),work.getUserName());
                results.add(workOrderResult);
            }
        }
        return results;
    }
    
    public void closeWorkOrder(Integer workOrderId) throws Exception {
        DbContextHolder.setDbType(Constants.DATASOURCE_SERVER);
        CfWorkorder workorder = cfWorkOrderMapper.selectByPrimaryKey(workOrderId);
        workorder.setOrderState(1);
        cfWorkOrderMapper.updateByPrimaryKey(workorder);
    }

}
